package homework.yuandan.config;

import homework.yuandan.beans.dto.UserDTO;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 作者:49293
 * 时间:2020/12/19-19:03
 * @author 49293
 */
@Component
public class TokenContainer {
    @Value("${config.jwt.secret}")
    private String secret;
    @Value("${config.jwt.expire}")
    private int expire;

    /**
     * 存储token的Map
     */
    private ConcurrentHashMap<Long, String> tokenMap = new ConcurrentHashMap<Long, String>();

    public void addToken(String token,Long userId){
        tokenMap.put(userId, token);
    }

    public ConcurrentHashMap<Long,String> getTokenMap(){
        return tokenMap;
    }

    private TokenContainer(){

    }

        public static TokenContainer newInstance(){
        return Builder.iContainer;
    }

    private static class Builder{
        private static TokenContainer iContainer = new TokenContainer();
    }



    /**
     * 使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
     * @param token dto对象
     * @return
     */
        public String createJavaWebToken(UserDTO token) {
        Calendar calendar = Calendar.getInstance();
            // 过期时间3天
        calendar.add(Calendar.SECOND, expire);
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id", token.getId());
        claims.put("img", token.getImg());
        claims.put("nickName", token.getNickName());
        claims.put("roleId",token.getRoleId());
        String tokenStr = Jwts.builder().setClaims(claims).setExpiration(
                // 设置过期时间
                calendar.getTime()).
                signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
        System.out.println("---");
        addToken(tokenStr, token.getId());
        token.setToken(tokenStr);
        return tokenStr;
    }

    /**
     * 该方法使用HS256算法和Secret:keyStr生成signKey
     * @return
     */
    private Key getKeyInstance() {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //keyStr = "lyf@we%sd(888)"
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("lyf@we%sd(888)");
        return new SecretKeySpec(apiKeySecretBytes,
                signatureAlgorithm.getJcaName());
    }

    /**
     * 解析Token，同时也能验证Token，当验证失败返回null
     * @param users token对象
     * @return useDTO对象
     */
    public UserDTO parserJavaWebToken(String users) {
        try {
            UserDTO jsJwtToken = null;
            Map<String, Object> jwtClaims = Jwts.parser().setSigningKey(
                    //密钥
                    getKeyInstance()).parseClaimsJws(users).getBody();
            if (null != jwtClaims) {
                jsJwtToken = new UserDTO();
                jsJwtToken.setId(Long.parseLong(jwtClaims.get("id").toString()));
                jsJwtToken.setImg(jwtClaims.get("img").toString());
                jsJwtToken.setNickName(jwtClaims.get("nickName").toString());
                jsJwtToken.setRoleId(Integer.parseInt(jwtClaims.get("roleId").toString()));
            }
            return jsJwtToken;
        } catch (Exception e) {
            return null;
        }
    }
}
